Skip to content

docs: add eight how-to guides + style-guide compliance sweep#50

Merged
andybons merged 1 commit into
mainfrom
docs-guides
Jul 15, 2026
Merged

docs: add eight how-to guides + style-guide compliance sweep#50
andybons merged 1 commit into
mainfrom
docs-guides

Conversation

@andybons

Copy link
Copy Markdown
Contributor

What

Closes the "guides worth writing" gaps from the documentation audit and runs the style-compliance sweep nobody had run.

Eight new task-oriented guides (docs/content/guides/11–18), each verified against code — every YAML snippet parse-checked through gatekeeper.LoadConfig, Go snippets compile-checked, and the container guide exercised live against the published 0.17.0 image:

  1. Deploying Behind a TCP Load Balancer — GCP proxyHeader: PROXY_V1 backend config, gatekeeper-first rollout ordering, client-IP-forgery caveats
  2. Running the Container Image — config/CA mounting, client wiring, and why in-container Docker healthchecks can't work on the distroless image (no shell)
  3. Postgres Data Plane with Neon — account- vs project-scoped API keys, the libpq host=/hostaddr= split for local testing without DNS
  4. Host Command Credentials — worked 1Password (op read) and pass examples
  5. GCP Service Account Tokens — three key-location modes and the precise rotation semantics (token-endpoint rejection drops the key only in Secret Manager mode)
  6. MCP Relay Setup — honest that MCP has no gatekeeper.yaml surface; Go-library path via RunContextData, compile-checked
  7. Credential Caching, Refresh, and Invalidation — startup fetch, 75%-of-TTL refresh (jitter applied after the 60s cap, so waits reach ~75s), token-exchange 1-min cache, 401/403 eviction
  8. Keep Policy Scopeshttp / mcp-<server> / llm-gateway, including that mcp-* denials set no X-Moat-Blocked header unlike the other two

Style-guide compliance sweep: concepts/ and guides/01–10 used Title Case headings while getting-started/ and reference/ were sentence case per docs/STYLE-GUIDE.md. 106 headings across 18 files converted, plus 4 terminology fixes (backendsource, SAN abbreviation order, two hedging removals). Behavior-neutral — no code, YAML, or link targets changed. New guides harmonized to the same conventions.

docs/README.md index updated; CHANGELOG v0.17.2 Added/Changed entry.

Review

Opus-reviewed: every high-risk guide claim spot-checked against code (the SetMCPServers signature, the jitter-after-cap math, the X-Moat-Blocked and gzip asymmetries, the distroless base image), the sweep confirmed behavior-neutral hunk-by-hunk, and one cross-guide contradiction on gcp-service-account key rotation was caught and fixed.

@claude

claude Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor
📦 Previous Review (superseded by newer review)

Claude finished @andybons's task in 4m 21s —— View job


Review complete

  • Gather context (PR body, changed files, AGENTS.md)
  • Run /code-review against the diff
  • Fact-check the new guides' technical claims against the actual code
  • Post summary

Summary

This PR touches no Go source — all 29 changed files are documentation (docs/, CHANGELOG.md). Per the repo's review priorities (security, races, bugs, error handling in the proxy code), there's nothing in scope for those categories. I instead spent the review verifying the PR's central claim — that every guide is "verified against code" — by cross-checking the highest-risk assertions directly against the implementation:

Claim Location Verified against
proxy_protocol fail-open, 10s header timeout, DEBUG log on malformed header guide 11 gatekeeper.go:750-895 — matches exactly, including the proxyProtoLogListener/proxyProtoLogConn DEBUG-only-on-genuine-parse-failure behavior
Distroless image has no shell, HEALTHCHECK/Compose exec-based probes can't work guide 12 consistent with cmd/gatekeeper/Dockerfile base image
Neon pagination truncates at 100, project-scoped keys can't list projects guide 13 credentialsource/neon.go:261-290len(projects.Projects) >= 100 matches "more than 99"
could not authenticate to upstream database / postgres upstream connection failed log line guide 13 proxy/postgres.go:758-763 — exact string match
sh -c execution, stderr truncated to 256 bytes, stdout never logged, empty-output error, already-expired Expiration rejected, control-char stripping guide 14 credentialsource/process.go — every claim matches line-for-line
gcp-service-account: key-drop-on-400/401/403 only wired when keySource != nil (Secret Manager mode); file/env modes have no backing source to re-read guide 15 credentialsource/gcpserviceaccount.go:113-127 + config_credential.go:91-124 — matches exactly
SetMCPServers/SetCredentialStore/MCPServerConfig/MCPAuthConfig/CredentialStore.GetToken signatures in the compile-checked Go snippet guide 16 proxy/proxy.go:105-135, 681, 758-763 — every type and field matches (go build itself wasn't permitted in this sandbox, but all symbols and signatures check out by inspection)
75%-of-TTL refresh floored at 30s; backoff 1s→doubling→60s cap, then up to 25% jitter added on top (so waits reach ~75s, not a strict 60s ceiling) guide 17 gatekeeper.go:603-650, 671 — matches precisely, including the jitter-after-cap detail called out in the PR description
mcp-<server> scope denials never set X-Moat-Blocked (plain http.Error), unlike http/llm-gateway guide 18 proxy/mcp.go:302-370 vs proxy/proxy.go:2049,2058,2499-2522,2888,2930 — confirmed by absence
llm-gateway gated on exact 200 + literal host == "api.anthropic.com"; gzip decompressed for llm-gateway but not http scope; SSE parsing stops at message_stop guide 18 proxy/proxy.go:2747, proxy/llmpolicy.go:41-117 — exact matches
407 for request-rule/host-service, 403 for keep-policy, 400 for llm-policy guide 18 proxy/proxy.go StatusProxyAuthRequired usages — matches the table

I also checked every internal Markdown link and anchor fragment across the eight new guides (guides/1118) — all resolve to real files and real headings, none broken.

The style-guide sweep (106 headings, concepts/ + guides/01–10) is behavior-neutral as claimed — sampled several files' diffs and confirmed the hunks are pure heading-case/terminology changes with no code, YAML, or link-target edits.

No findings. I did not identify any factual inaccuracy, broken reference, or security-guidance gap in the new content — the load-balancer and container guides both correctly warn about client_ip forgery risk and recommend firewalling direct access, and the process-credentials guide correctly flags that command is arbitrary code execution as the gatekeeper process and should only come from trusted config.

…ompliance

New task-oriented guides (11-18) for features that had only reference
coverage: TCP load balancer / PROXY protocol deployment, running the
container image, Postgres data plane with Neon, host command credentials,
GCP service account tokens, MCP relay setup, the credential lifecycle,
and Keep policy scopes. Every YAML snippet is parse-checked through
gatekeeper.LoadConfig, Go snippets compile-checked, and the container
guide was exercised live against the published image.

Also runs the style-guide compliance sweep nobody had run: 106 headings
across 18 existing pages converted from Title Case to sentence case to
match getting-started/ and reference/, plus scattered terminology fixes.
@claude

claude Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Claude finished @andybons's task in 2m 7s —— View job


Reviewing PR #50

  • Gather context (PR body, changed files, AGENTS.md)
  • Run /code-review against the diff
  • Fact-check new guides' technical claims and sample the style sweep
  • Post summary

Summary

This PR is docs-only (docs/, CHANGELOG.md) — no Go source changed, so there's nothing in scope for the repo's usual security/race/error-handling review priorities. This trigger reran against the same single commit already reviewed in my previous pass (identical diff vs. origin/main), so I re-verified the highest-risk claims directly against the current code rather than re-treading ground:

Claim Location Verified against
network.proxy_protocol config field, fail-open, 10s header timeout guide 11 config.go:129, gatekeeper.go:824
Dockerfile: distroless base, ENTRYPOINT ["/gatekeeper"], no shell guide 12 cmd/gatekeeper/Dockerfile
GATEKEEPER_CONFIG env fallback, /healthz returns {"status":"ok"} unauthenticated guide 12 cmd/gatekeeper/main.go:140, gatekeeper.go:180-193
Postgres listener refuses to start without tls.ca_cert/tls.ca_key guide 12, 13 gatekeeper.go:270 (exact error string match)
Only process, github-app, gcp-service-account implement RefreshingSource (not aws-secretsmanager/gcp-secretmanager) guide 17 summary table credentialsource/{process,githubapp,gcpserviceaccount}.go — confirmed no other source defines TTL()
Startup fetch 10s timeout; refresh backoff 1s→doubling→60s cap guide 17 gatekeeper.go:557,627,669 (fetch), gatekeeper.go:646-650 (backoff)
Token-exchange: 1-minute cache cap, 10s invalidation cooldown, singleflight coalescing guide 17 credentialsource/tokenexchange.go:153 (maxTokenTTL), :164 (defaultInvalidateCooldown) — exact match
http scope: duplicate-JSON-key bodies rejected as a bypass vector guide 18 proxy/proxy.go:311-349 — comment and logic match the guide's stated rationale precisely
oauth: grant prefix → Bearer prepended guide 16, 18 proxy/mcp.go:63-64
SSE relay reads in 4096-byte chunks guide 16 proxy/stream.go:44

Every numeric/behavioral claim I checked matches the implementation exactly, including the more subtle ones (jitter-after-cap producing ~75s not a strict 60s ceiling, gcp-service-account key-drop being Secret Manager-mode-only, the duplicate-key JSON rejection rationale).

I also sampled two of the style-sweep diffs (concepts/03-credential-sources.md, guides/06-token-exchange.md) — confirmed hunk-by-hunk that the changes are pure heading-case conversions (Title Casesentence case) with no wording, code, YAML, or link-target changes.

No findings. Nothing to flag from this pass — the guides' technical claims and the style sweep both hold up against the current codebase.

@andybons andybons merged commit ed71149 into main Jul 15, 2026
2 checks passed
@andybons andybons deleted the docs-guides branch July 15, 2026 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant